<template>
  <el-form ref="FormRef" :model="searchForm" :rules="rules" class="filter-bar" @submit.prevent>
    <div class="filter-wrapper">
      <el-row :gutter="24">
        <el-col v-for="(item,index) in source" :key="index" :span="item.span || 8">
          <el-form-item :label="item.label" :prop="item.prop" :label-width="item.width || '100px'">
            <FilterItemInput
              :disabled="item.isDisabled"
              v-model="searchForm[item.prop]"
              :type="item.type"
              :multiple="item.multiple"
              :filterable="item.filterable"
              :controlsPosition="item.controlsPosition"
              :input-props="item.inputProps"
              :suffix-icon="item.suffixIcon"
              :icon="item.icon"
              @change="(val)=>handleEvents(val,'change',item)"
              @onChange="(val)=>handleEvents(val,'onChange',item)"
              @click="(val)=>handleEvents(val,'click',item)"
              @beforeUpload="beforeUpload"
            />
            <span v-if="item.remark">{{ item.remark }}</span>
          </el-form-item>
        </el-col>
      </el-row>
      <FilterButtonGroup
        :is-collapse="isCollapse"
        :is-toggle="isToggle"
        :hasButton="hasButton"
        :hasTableButton="hasTableButton"
        @on-search="onSearch"
        @on-reset="onReset"
      />
    </div>
  </el-form>
</template>

<script lang="ts" setup>
  import { reactive, ref, toRaw, watchEffect } from 'vue'
  import FilterItemInput from '@/components/FilterBar/components/filter-item-input.vue'
  import FilterButtonGroup from '@/components/FilterBar/components/filter-button-group.vue'
  import type { FilterItem, FieldsItemType } from '@/components/FilterBar/types'
  import type { FormInstance, FormRules } from 'element-plus'
  // 7-17增加hasButton属性用于layoutcard窗口中确认  取消按钮的显示和隐藏;
  const props = defineProps<{
    filters: FilterItem[], hasButton: hasButton, multiple: multiple, filterable?: filterable, icon: icon
    hasTableButton: hasTableButton, modelValue: modelValue, rules?: any
  }>()
  const emits = defineEmits(['search-change', 'search-reset'])

  const offset = ref(0)
  const isCollapse = ref(false)
  const source = ref(props.filters.slice(0))

  const isToggle = true
  const models = props.filters.reduce((previous, current) => {
    return Object.assign(previous, { [current.prop]: current.defaultValue })
  }, {})
  const searchForm = reactive<FieldsItemType>(models)
  const FormRef = ref<FormInstance>()

  const getParams = () => {
    const data = toRaw(searchForm)
    return Object.keys(data).reduce((pre, cur) => {
      return Object.assign(pre, { [cur]: data[cur] || undefined })
    }, {})
  }

  // 7-28增加upload相关方法
  const beforeUpload = (rawFile) => {
    emits('beforeUpload', rawFile)
  }
  /**
   * 点击查询
   */
  const onSearch = () => {
    emits('search-change', getParams())
  }

  /**
   * 点击重置按钮
   */
  const onReset = () => {
    console.log(searchForm)
    FormRef.value?.resetFields()
    props.filters.forEach(v => {
      searchForm[v.prop] = v.defaultValue
    })
    emits('search-reset', getParams())
  }

  // ========更新字段及数据源API
  const handleEvents = (value: string, event: string, itr: FilterItem) => {
    const functions = itr.events?.[event]
    if (functions) {
      const func = {
        setFieldsValue,
        setOptions
      }
      functions(value, func)
    }
  }
  const setFieldsValue = (data: FieldsItemType) => {
    Object.keys(data).forEach(key => {
      searchForm[key] = data[key]
    })
  }
  const setOptions = (key: string, data: []) => {
    source.value.forEach(col => {
      if (col.prop === key && col.inputProps) {
        col.inputProps.options = data
      }
    })
  }

  watchEffect(() => {
    const length = source.value.length
    if (length % 3 === 0) {
      offset.value = 16
    } else if (length % 3 === 1) {
      offset.value = 8
    } else {
      offset.value = 0
    }
  })
  // 子组件定义验证方法
  const validateRuleFormRef = async () => {
    // 校验成功则方法自动返回true，校验方法报错则说明校验失败，返回false
    try {      
      return await FormRef.value.validate()
    } catch (error) {
      return false
    }
  }
  // 将方法暴露出去
  defineExpose({
    setFieldsValue,
    setOptions,
    getParams,
    validateRuleFormRef,
    onReset
  })
</script>

<style lang="less" scoped>
  .filter-bar {
    .filter-wrapper {
      display: flex;
      justify-content: space-between;
      align-items: flex-start;
      >.el-row {
        flex: 1;
      }
    }
    :deep(.el-col) {
      padding-right: 16px !important;
    }
    .el-form-item {
      width: 100%;
      margin-bottom: 24px;
      :deep(.el-form-item__label) {
        min-width: 68px;
      }
      .only-one {
        width: 260px!important;
      }
    }
  }
</style>
